import { ForbiddenException, Injectable } from '@nestjs/common';
import { 
    CreateStudentDto,
    UpdateStudentDto,
    QueryStudentDto,
  } from './dto/student.dto';
import { InjectRepository, InjectEntityManager } from '@nestjs/typeorm';
import { Repository, EntityManager, In} from 'typeorm';
import { Student } from './entities/student.entity';
import { ApiTags } from '@nestjs/swagger';
import { Workbook } from 'exceljs';
import { Request, Response } from 'express';
import { User } from '../user/entities/user.entity';

@ApiTags('学生表')
@Injectable()
export class StudentService {
  constructor(
    @InjectRepository(Student) private readonly student: Repository<Student>,
    @InjectEntityManager() private entityManager: EntityManager,
  ) {}

  /**
   * 创建学生表
   * @param createStudentDto
   * @returns
   */
  async create(createStudentDto: CreateStudentDto, req: Request) {
    let user = req.user as User;
    let params = createStudentDto.form;
    params.create_by = user.username;
    return this.student.save(params);
  }

  /**
   * 学生表列表
   * @param query
   * @returns
   */
  async findAll(query: QueryStudentDto) {
    let queryBuilder = this.student.createQueryBuilder('student');
    // 处理查询条件
        
    if (query.age) {
      queryBuilder = queryBuilder.andWhere('student.age = :key', {
        key: `${query.age}`,
      });
    }
        
    if (query.class) {
      queryBuilder = queryBuilder.andWhere('student.class = :key', {
        key: `${query.class}`,
      });
    }
        
    if (query.name) {
      queryBuilder = queryBuilder.andWhere('student.name LIKE :key', {
        key: `%${query.name}%`,
      });
    }

    // 处理分页
    if (!query.pageNum || query.pageNum < 1) {
      query.pageNum = 1;
    }
    if (!query.pageSize || query.pageSize < 1) {
      query.pageSize = 10;
    }
    queryBuilder = queryBuilder
      .skip((query.pageNum - 1) * query.pageSize)
      .take(query.pageSize)
    let total = await queryBuilder.getCount();
    let list = await queryBuilder.getMany();
    return {
      pageNum: query.pageNum,
      pageSize: query.pageSize,
      total,
      list,
    };
  }

  /**
   * 学生表详情
   * @param id
   * @returns
   */
  async findOne(id: number) {
    let data = await this.student.findOne({
      where: {
        id: id,
      },
    });
    return {
      data
    };
  }

  /**
   * 修改学生表
   * @param id
   * @param updateStudentDto
   * @param req
   * @returns
   */
  async update(id: number, updateStudentDto: UpdateStudentDto,req:Request) {
    let params = updateStudentDto.form;
    let user = req.user as User;
    params.update_by = user.username
    return this.student.update(id, params);
  }

  /**
   * 删除学生表
   * @param ids
   * @returns
   */
  async remove(ids: number[]) {
    try {
      await this.entityManager.transaction(async (manager) => {
        await manager.delete(Student, { id: In(ids) });
      });
    } catch (err) {
      return err;
    }
  }

  /**
   * 导出为表格
   * @param res
   */
  async exportToExcel(res: Response) {
    const workbook = new Workbook();
    const worksheet = workbook.addWorksheet('学生表');

    worksheet.columns = [
      { header: '年龄', key: 'age', width: 10 },
      { header: '班级', key: 'class', width: 10 },
      { header: 'id', key: 'id', width: 10 },
      { header: '姓名', key: 'name', width: 10 },
    ];

    const data = await this.student.find();
    worksheet.addRows(data);
    res.setHeader(
      'Content-Type',
      'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
    );
    let filename = encodeURIComponent('学生表.xlsx')  // 这里中文需要转码
    res.setHeader('Content-Disposition', 'attachment; filename='+filename+'');
    res.setHeader('Cache-Control', 'max-age=0');
    const file = await workbook.xlsx.writeBuffer();
    res.end(file)
  }
}
